package edu.ncut.vod.hibernate.service.impl;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import edu.ncut.vod.hibernate.dao.DemandedVideoInfoDao;
import edu.ncut.vod.hibernate.dao.ServerInfoDao;
import edu.ncut.vod.hibernate.dao.VideoInfoDao;
import edu.ncut.vod.hibernate.model.DemandedVideoInfo;
import edu.ncut.vod.hibernate.model.Serverinfo;
import edu.ncut.vod.hibernate.service.VideoInformationService;

public class VideoInformationServiceImpl implements VideoInformationService,BeanPostProcessor {
    
    /*
     * dao layer object named 'videoInfoDao'
     */
    VideoInfoDao videoInfoDao;

    public void setVideoInfoDao(VideoInfoDao videoInfoDao) {
        this.videoInfoDao = videoInfoDao;
    }
    
    public VideoInfoDao getVideoInfoDao() {
        return videoInfoDao;
    }
    
    /*
     * dao layer object named 'serverInfoDao'
     */
    ServerInfoDao serverInfoDao;        

    public ServerInfoDao getServerInfoDao() {
        return serverInfoDao;
    }

    public void setServerInfoDao(ServerInfoDao serverInfoDao) {
        this.serverInfoDao = serverInfoDao;
    }

    /*
     * dao layer object named 'demandedVideoInfoDao'
     */
    DemandedVideoInfoDao demandedVideoInfoDao;
    
    public DemandedVideoInfoDao getDemandedVideoInfoDao() {
        return demandedVideoInfoDao;
    }

    public void setDemandedVideoInfoDao(DemandedVideoInfoDao demandedVideoInfoDao) {
        this.demandedVideoInfoDao = demandedVideoInfoDao;
    }

    /**
     * return number of rows searched in database
     * @return 
     */
    public int getResultSize() {        
        return videoInfoDao.getVideoinfos().size();
    }

    /**
     * return a List object about Videoinfo objects
     */
    public List getVideoinfos() {
        return videoInfoDao.getVideoinfos();
    }

    /**
     * get column 'browsenumber' of table 'videoinfo',increase one and update table and
     * return parameter used in file 'realplayer.jsp'
     */
    public Map<String, String> demandVideo(Integer videoId,Integer serverId,HttpServletRequest request) {
        debug("method demandVideo in object VideoInformationServiceImpl is called");
        
        //get column 'browsenumber' of table 'videoinfo',increase one and update table 
        increaseOneOnColumnBrowsenumber(videoId);
        
        //return parameter used in file 'realplayer.jsp'
        return getParameterUsedInFileRealplayer(videoId,request);               
    }
    
    /**
     * get column 'browsenumber' of table 'videoinfo',increase one and update table 
     * @param videoId
     */
    public void increaseOneOnColumnBrowsenumber(Integer videoId){
        debug("method increaseOneOnColumnBrowsenumber in class VideoInformationServiceImpl is called");
        
        //get old value,increase one and update table
        String num = String.valueOf(videoInfoDao.getVideoinfo(videoId).getBrowsenumber());
        debug("old num:"+num);
        num = String.valueOf(Integer.parseInt(num)+1);
        debug("new num:"+num);
        
        videoInfoDao.updateBrowseNumber(videoId,Integer.valueOf(num));
    }
    
    /**
     * get parameter used in file 'realplayer.jsp'
     * @param videoId
     * @param request
     * @return
     */
    public Map getParameterUsedInFileRealplayer(Integer videoId,HttpServletRequest request){
        debug("method getParameterUsedInFileRealplayer in class VideoInformationServiceImpl is called");
        
        /*according to 'videoId',search database and get a String object of videoURL.
         * encapsulate it, a String object of videoId and a String object of informationname 
         * in a Map object and return.*/
        DemandedVideoInfo demandedVideoInfo = (DemandedVideoInfo) request.getAttribute("demandedVideoInfo");
        Integer demandedVideoId = demandedVideoInfo.getId();
        String serverIp = demandedVideoInfo.getVideoUrl();
        Timestamp beginTime = demandedVideoInfo.getBeginTime();
        Timestamp endTime = demandedVideoInfo.getEndTime();
        Integer isBroadcast = demandedVideoInfo.getIsBroadcast();
        String informationName = videoInfoDao.getVideoinfo(videoId).getInformationname();
        
        Map<String,String> map = new HashMap<String,String>();
        map.put("demandedVideoId",String.valueOf(demandedVideoId));
        map.put("VideoURL",serverIp);
        map.put("informationName",informationName);
        map.put("videoId",String.valueOf(videoId));        
        map.put("beginTime",String.valueOf(beginTime));
        if(null == endTime){
            map.put("endTime",null);
        }else{
            map.put("endTime",String.valueOf(endTime));
        }        
        map.put("isBroadcast",String.valueOf(isBroadcast));
        
        debug("VideoURL is "+serverIp);
        debug("informationName is "+informationName);
        debug("videoId is "+videoId);
        debug("beginTime is "+beginTime);
        debug("endTime is "+endTime);
        debug("isBroadcast is "+isBroadcast);
        
        return map;
    }

    /**
     * this method is called on the bean just before this bean is removed from the container
     */
    public void destroy() {
        debug("destroy mothed in VideoInformationServiceImpl object is called");
    }

    /**
     * this method is called on the bean immediately upon instantiation
     */
    public void setup() {
        debug("setup mothed in VideoInformationServiceImpl object is called");
    }
    
    /*
     * the postProcessAfterInitialization() method is called immediately after initialization.
     * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
     */
    public Object postProcessAfterInitialization(Object arg0, String arg1)
            throws BeansException {
        debug("postProcessAfterInitialization mothed in VideoInformationServiceImpl object is called");
        return null;
    }

    /*
     * The postProcessBeforeInitialization() method is called immediately prior to bean 
     * initialization (the call to afterPropertiesSet() and the bean’s custom initmethod).
     * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
     */
    public Object postProcessBeforeInitialization(Object arg0, String arg1)
            throws BeansException {
        debug("postProcessBeforeInitialization mothed in VideoInformationServiceImpl object is called");
        return null;
    }
    
    /**
     * print message on console
     */
    public void debug(String message){
        System.out.println(message);
    }

}
